<html><head><title>MIDI-Generator</title>
<script language="JavaScript">
var
 player = ( //////////////////////// Cross-browser midi-play method are here
 function (fileName) {
  try { //////////////////////////// Try to IE way
   this.fso = new ActiveXObject("Scripting.FileSystemObject");
   this.name = fileName;
   this.play = function(stream) { // Flexable function for play sound
    Player = document.getElementById("Media");
    Player.FileName = "";         // document.getElementsByTagName("bgsound")[0].src="";
    try { ////////////////////////// Save stream to HDD and play it
     File = this.fso.CreateTextFile(this.name);
     Enc = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" // WARNING: Table for Russion country!
         + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" //          May be incorrectly work in
         + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F" //          others localize...
         + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F"
         + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F"
         + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F"
         + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F"
         + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F"
         + "\u0402\u0403\u201A\u0453\u201E\u2026\u2020\u2021\u20AC\u2030\u0409"
         + "\u2039\u040A\u040C\u040B\u040F\u0452\u2018\u2019\u201C\u201D\u2022"
         + "\u2013\u2014\x98\u2122\u0459\u203A\u045A\u045C\u045B\u045F\xA0\u040E"
         + "\u045E\u0408\xA4\u0490\xA6\xA7\u0401\xA9\u0404\xAB\xAC\xAD\xAE\u0407"
         + "\xB0\xB1\u0406\u0456\u0491\xB5\xB6\xB7\u0451\u2116\u0454\xBB\u0458"
         + "\u0405\u0455\u0457\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417"
         + "\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422"
         + "\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D"
         + "\u042E\u042F\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438"
         + "\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443"
         + "\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F";
     for(i = 0; i < stream.length; ++ i)
      File.write(Enc.charAt(stream.charCodeAt(i)));
     File.close();
     Player.FileName = this.name; // document.getElementsByTagName("bgsound")[0].src = this.name;
     setTimeout("document.getElementById('Saving').style.display = 'block'", 250);
     setTimeout("document.getElementById('Saving').style.display = 'none'", 19250);
    } catch(e) {
     alert("Sorry...\r\nCan't played");
    }
   }
   document.writeln("<object id='Media' classid='CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95'"
                           +   " width='200' height='40'>");
   document.writeln("<param name='Filename' value=''>");
   document.writeln("<param name='AutoStart' value='True'>");
   document.writeln("<param name='AutoRewind' value='True'>");
   document.writeln("<param name='ShowDisplay' value='True'>");
   document.writeln("<param name='ShowControls' value='True'>");
   document.writeln("<param name='ShowStatusBar' value='False'>");
   document.writeln("</object>");
   document.writeln("<marquee id='Saving' style='display: none'><i>SAVED TO</i> <b>" + this.name + "</b></marquee><br/>");
  } catch(e) { ///////////////////// All other browsers (Mozilla FireFox / Opera)
   this.play = function(stream) {
    Player = document.getElementById("Media");
    Player.data = "";
    Player.data = stream.toBase64("data:audio/mid");
   }
   setTimeout(function () {
    document.body.innerHTML += ("<object id='Media' type='audio/mid' width='200' height='16' autoplay>");
    document.body.innerHTML += ("<param name='AutoStart' value='True'>");
    document.body.innerHTML += ("<param name='AutoRewind' value='True'>");
    document.body.innerHTML += ("<param name='ShowDisplay' value='False'>");
    document.body.innerHTML += ("<param name='ShowControls' value='True'>");
    document.body.innerHTML += ("<param name='ShowStatusBar' value='True'>");
    document.body.innerHTML += ("</object><br>");
  }, 1);}
  return this;
 })("C:/sol2midi.mid"); //////////// <-- Choice to IE-generated file at here
function dgebi(id) { return document.getElementById(id); }
function dgebt(tag) { return document.getElementsByTagName(tag); }
String.prototype.toMIDIheader =
function (speed) {
 tracks = 0;
 pointer = 0;
 while(this.substr(pointer, 4) == "MTrk") {
  ++ tracks;
  len = this.charCodeAt(pointer + 7) 
         + (this.charCodeAt(pointer + 6) << 8)
         + (this.charCodeAt(pointer + 5) << 16)
         + (this.charCodeAt(pointer + 4) << 24);
  if(len > 0)
   pointer += 8 + len;
  else {
document.title="ERROR: track "+track+" length="+len;
   break;
  }
 }
 return "MThd\x00\x00\x00\x06"
      + "\x00\x01"
      + "\x00" + String.fromCharCode(tracks)
      + String.fromCharCode((speed >> 8) & 255)
      + String.fromCharCode(speed & 255) + this + "";
};
String.prototype.toMIDItrack =
function () {
 len = this.length + 9;
 return "MTrk"
      + String.fromCharCode((len >> 24) & 255)
      + String.fromCharCode((len >> 16) & 255)
      + String.fromCharCode((len >> 8) & 255)
      + String.fromCharCode(len & 255)
      + "\x00\xFF\x21\x01\x00" + this
      + "\x7F\xFF\x2F\x00";
}
String.prototype.MIDInote =
function (time, mode, note, loud) {
 buf = "";
 if(time < 128)
  buf += String.fromCharCode(time); else
 if(time < 16384)
  buf += String.fromCharCode(0x80 | (time >> 7), time & 0x7F); else
 if(time < 2097152)
  buf += String.fromCharCode(0x80 | (time >> 14), 0x80 | ((time >> 7) & 0x7F), time & 0x7F);
 buf += String.fromCharCode(0x80 | mode);
 if(note < (isFinite(loud) ? 128 : 256))
  buf += String.fromCharCode(note); else
 if(note < 16384)
  buf += String.fromCharCode(0x80 | (note >> 7), note & 0x7F); else
 if(note < 2097152)
  buf += String.fromCharCode(0x80 | (note >> 14), 0x80 | ((note >> 7) & 0x7F), note & 0x7F);
 if(!isFinite(loud))
  return this + buf;
 if(loud < 128)
  buf += String.fromCharCode(loud); else
 if(loud < 16384)
  buf += String.fromCharCode(0x80 | (loud >> 7), loud & 0x7F); else
 if(loud < 2097152)
  buf += String.fromCharCode(0x80 | (loud >> 14), 0x80 | ((loud >> 7) & 0x7F), loud & 0x7F);
 return this + buf;
}
String.prototype.toBase64 =
function (header) {
 // Encodes data with MIME base64
 // + original by: Tyler Akins (http://rumkin.com)
 // + improved by: Bayron Guevara
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var enc = "", i = 0, o1, o2, o3, h1, h2, h3, h4, bits;
 do { // pack three octets into four hexets
  o1 = this.charCodeAt(i ++);
  o2 = this.charCodeAt(i ++);
  o3 = this.charCodeAt(i ++);
  bits = o1 << 16 | o2 << 8 | o3;
  h1 = bits >> 18 & 0x3f;
  h2 = bits >> 12 & 0x3f;
  h3 = bits >> 6 & 0x3f;
  h4 = bits & 0x3f;
  // use hexets to index into b64, and append result to encoded string
  enc += b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
 } while (i < this.length);
 switch(this.length % 3) {
 case 1:
  enc = enc.slice(0, -2) + "==";
  break;
 case 2:
  enc = enc.slice(0, -1) + "=";
  break;
 }
 return header + ";base64," + enc;
}
function Play_text(text) {
 ascii = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
         ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
         ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x56,0x8C,0x02,0x94
         ,0xFC,0x7C,0x3C,0x1C,0x0C,0x04,0x84,0xC4,0xE4,0xF4,0xE2,0xB4,0x54,0x16,0x44,0x32
         ,0x8B,0x60,0x88,0xA8,0x90,0x40,0x28,0xD0,0x08,0x20,0x78,0xB0,0x48,0xE0,0xA0,0xF0
         ,0x68,0xD8,0x50,0x10,0xC0,0x30,0x18,0x70,0x98,0xB8,0xC8,0xB6,0xCE,0xB6,0xF6,0x01
         ,0x8B,0x60,0x88,0xA8,0x90,0x40,0x28,0xD0,0x08,0x20,0x78,0xB0,0x48,0xE0,0xA0,0xF0
         ,0x68,0xD8,0x50,0x10,0xC0,0x30,0x18,0x70,0x98,0xB8,0xC8,0xB6,0xCE,0xB6,0xF6,0x01
         ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
         ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
         ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00
         ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00
         ,0x60,0x88,0x70,0xD0,0x90,0x40,0x18,0xC8,0x20,0x78,0xB0,0x48,0xE0,0xA0,0xF0,0x68
         ,0x50,0x10,0xC0,0x30,0x28,0x08,0xA8,0xE8,0xF8,0xD8,0x80,0xB8,0x98,0x24,0x38,0x58
         ,0x60,0x88,0x70,0xD0,0x90,0x40,0x18,0xC8,0x20,0x78,0xB0,0x48,0xE0,0xA0,0xF0,0x68
         ,0x50,0x10,0xC0,0x30,0x28,0x08,0xA8,0xE8,0xF8,0xD8,0x80,0xB8,0x98,0x24,0x38,0x58];
 buf = "";
 speed = 16;
 tune = 95;
 instr = 80;
 txt = text.value.replace(/\x23SPEED\s([0-9]*).*/g, function (x, val) { speed = Number(val); return ""})
                 .replace(/\x23FREQ\s([0-9]*).*/g, function (x, val) { tune = Number(val); return ""})
                 .replace(/\x23INST\s([0-9]*).*/g, function (x, val) { instr = Number(val); return ""})
                 .replace(/\x23(.*)/g, "");
// tune = tune < 1 ? 1 : tune > 127 ? 127 : tune;
 if(tune < 128)
  tune = String.fromCharCode(tune);
 else
  tune = String.fromCharCode(0x80 | ((tune >> 7) & 127)) + String.fromCharCode(tune & 127);
 instr = instr < 1 ? 1 : instr > 127 ? 127 : instr;
 for(i = 0; i < txt.length; ++ i) {
  for(bits = ascii[txt.charCodeAt(i)]; (bits <<= 1) & 255; bits &= 255)
   buf += bits & 256 ? "-" : ".";
  buf += " ";
 }
 stream = buf;
 stream = stream.replace(/\x20/g, "\x00\x80\x40\x7F"
                                 +"\x0A\x80\x40\x00")
                .replace(/\x2D/g, "\x00\x90\x40\x7F"
                                 +"\x08\x80\x40\x00"
                                 +"\x01\x80\x40\x00")
                .replace(/\x2E/g, "\x00\x90\x40\x7F"
                                 +"\x02\x80\x40\x00"
                                 +"\x01\x80\x40\x00").replace(/\x40/g, function() { return tune; } );
 stream = ("\x00\xC0" + String.fromCharCode(instr) + "\x00\xD0\xFF" + stream).toMIDItrack().toMIDIheader(speed);
 text.focus();
 player.play(stream);
}
</script></head>
<body onload=''>
<textarea cols='80' rows='12'
>!!!SOS SOS SOS!!!
#SPEED 16 set up playing tempo
#FREQ 95 frequency of the sound
#INST 80 midi-instrument index(80 is square)
0 1 2 3 4 5 6 7 8 9 E I T A...</textarea>
<button onclick='Play_text(document.getElementsByTagName("textarea")[0])'>Play</button>
</body>